#include <string>
#include "extension/colors.h"
using namespace std;
using namespace bend2d;

static int xioctl (int fd, int request, void * arg);
class videoCapture 
{
    public:
        typedef enum {
            IO_METHOD_READ,
            IO_METHOD_MMAP,
            IO_METHOD_USERPTR,
        } ioMethod;

        struct buffer
        {
            unsigned char  *buff;
            unsigned char  *cbuff;
            unsigned int   *uibuff;
            unsigned int   *uicbuff;
            unsigned short *usbuff;
            unsigned short *uscbuff;
            Color          *colorbuff;

            size_t buffsize;
            size_t cbuffsize;
            size_t word;
            size_t cword;

            buffer(size_t _buffsize, size_t _cbuffsize, size_t _word, size_t _cword) :
                buffsize(_buffsize), cbuffsize(_cbuffsize), word(_word), cword(_cword) 
            {
                // TODO use words to create the buffers //
                buff = new unsigned char [buffsize];
                cbuff = new unsigned char [cbuffsize];
                uibuff = (unsigned int*)buff;
                uicbuff = (unsigned int*)cbuff;
                usbuff = (unsigned short*)buff;
                uscbuff = (unsigned short*)cbuff;
                colorbuff = new Color[buffsize / 2];
            }

            ~buffer()
            {
                delete [] buff;
                delete [] cbuff;
                delete [] colorbuff;
            }
        };

        videoCapture();
        ~videoCapture();
        bool openVideoDevice(const string& dev);
        bool initDevice();
        void initRead (unsigned int buffer_size);
        int readFrame ();
        void convertBuffer(buffer *ptr);
        virtual void filter(int position, Color& color) {}

        // Buffer Manip Functions //
        buffer* getBuffers() { return m_Buffers; }
        const buffer* getBuffers() const { return m_Buffers; }
        const Color& getPixelColor(int x, int y) const;
        const Color& getPixelColor(int pos) const;

        // Other //
        const string& GetDeviceName() const { return m_Device; }
        void SkipReading(bool value);

     private:
        int m_DevFD;
        string m_Device;
        ioMethod m_IOMethod;
        buffer* m_Buffers;
        bool m_SkipReading;
};


